package com.dgut.edu.cn.design.mode.filterchain;

import com.alibaba.fastjson.JSONArray;
import com.dgut.edu.cn.design.mode.filterchain.dto.PriceCompareResult;
import com.dgut.edu.cn.design.mode.log.LogMsgKit;
import com.dgut.edu.cn.design.mode.utils.CfgCenterUtils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: hongbin.zheng
 * @create: 2023-08-11 11:15
 **/
@Slf4j
@Service
public class FilterChainService {

	@Autowired
	private FilterChainFactory filterChainFactory;

	/**
	 * 生成的过滤链
	 */
	private Map<String,FilterChain<PriceCompareResult>> filterChains = Maps.newHashMap();

	/**
	 * 老配置的md5
	 */
	private String oldConfigMd5;
	/**
	 * 批量进行过滤
	 *
	 * @param priceCompareResults
	 * @return
	 */
	public List<PriceCompareResult> batchExecute(List<PriceCompareResult> priceCompareResults, MyFilterChainType type) {
		checkChains();
		return priceCompareResults.stream()
				.filter(priceCompareResult -> executeWithoutCheckChains(priceCompareResult, type) != null)
				.collect(Collectors.toList());

	}

	private void checkChains() {
		try {
			String filterChainConfig = CfgCenterUtils.getCfgString("PC_RESULT_FILTER_CHAIN", "");
			if (StringUtils.isEmpty(filterChainConfig)) {
				log.info(LogMsgKit.of("checkChains").p("filterChainConfig", filterChainConfig).end("配置为空"));
				return;
			}
			String newConfigMd5 = DigestUtils.md5DigestAsHex(filterChainConfig.getBytes());
			if (!newConfigMd5.equals(oldConfigMd5)) {
				List<FilterChainConfig> configs = JSONArray.parseArray(filterChainConfig, FilterChainConfig.class);
				Map<String,FilterChain<PriceCompareResult>> map = Maps.newHashMap();
				for (FilterChainConfig config : configs) {
					FilterChain<PriceCompareResult> chain = filterChainFactory.createChains(config,
							PriceCompareResult.class);
					map.put(chain.getName(),chain);

				}
				oldConfigMd5 = newConfigMd5;
				filterChains.clear();
				filterChains = map;
			}
		} catch (Exception e) {
			log.error(LogMsgKit.of("PcResultFilterAdmin_checkChains").end("新增或更新过滤链失败"), e);
		}
	}


	public PriceCompareResult executeWithoutCheckChains(PriceCompareResult compareResult, MyFilterChainType type) {
		FilterChain<PriceCompareResult> chain = filterChains.get(type.getName());
		if (chain == null) {
			log.warn(LogMsgKit.of("PcResultFilterAdmin_executeWithoutCheckChains").p("FilterType", type).end("没有该过滤链"));
			return null;
		}
		try {
			return chain.process(compareResult);
		} catch (Exception e) {
			log.error(LogMsgKit.of("PcResultFilterAdmin_executeWithoutCheckChains").p("filterChain", chain).p("result", compareResult)
					.end("执行失败"), e);
		}
		return compareResult;
	}

}
